package notification

import (
	"crypto/tls"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"

	"github.com/denverdino/aliyungo/sms"

	"gitee.com/dayu1985/framework/encoding/cryption"
	"gitee.com/dayu1985/framework/logging"
	"gitee.com/dayu1985/framework/utils"
)

type SMSNotification interface {
	SMS(mobile, template string, param map[string]string) error
}

type IAliSMSNotification struct {
	client   *sms.Client
	Domain   string
	SignName string
}

func NewIAliSMSNotification(sign, key, secret string) SMSNotification {
	return &IAliSMSNotification{
		Domain:   "https://sms.aliyuncs.com/",
		SignName: sign,
		client:   sms.NewClient(key, secret),
	}
}

func (s *IAliSMSNotification) SMS(mobile, template string, params map[string]string) error {

	str := utils.MustJSONString(params)

	logging.Info("发送短信： %s - %s", template, str)

	return s.client.SingleSendSms(&sms.SingleSendSmsArgs{
		SignName:     s.SignName,
		TemplateCode: template,
		RecNum:       mobile,
		ParamString:  str,
	})
}

type IHuyiSMSNotification struct {
	Domain   string
	Account  string
	Password string
}

func NewIHuyiSMSNotification(account, password string) SMSNotification {
	return &IHuyiSMSNotification{
		Domain:   "http://106.ihuyi.cn/webservice/sms.php",
		Account:  account,
		Password: password,
	}
}

func (s *IHuyiSMSNotification) SMS(mobile, template string, params map[string]string) error {

	req, err := url.Parse(s.Domain)

	if err != nil {
		return err
	}

	query := req.Query()

	query.Set("account", s.Account)
	query.Set("password", s.Password)
	query.Set("method", "Submit")
	query.Set("mobile", mobile)
	query.Set("content", template)

	req.RawQuery = query.Encode()

	logging.Info("发送短信： %s - %s", mobile, template)

	resp, err := http.Get(req.String())

	if err != nil {
		return err
	}

	defer resp.Body.Close()
	bs, err := ioutil.ReadAll(resp.Body)

	logging.Info(string(bs))

	if err != nil {
		return err
	}

	return nil
}

type IEntInfoSMSNotification struct {
	Domain   string
	Sn       string
	Password string
}

func NewIEntInfoSMSNotification(d, sn, password string) SMSNotification {
	return &IEntInfoSMSNotification{
		Domain:   d,
		Sn:       sn,
		Password: password,
	}
}

func (s *IEntInfoSMSNotification) SMS(mobile, template string, params map[string]string) error {

	var postParams = url.Values{}
	postParams.Add("sn", s.Sn)                                    //sn软件序列号
	postParams.Add("pwd", cryption.GetMd5String(s.Sn+s.Password)) //pwd加密密码md5(sn+password);
	postParams.Add("mobile", mobile)                              //mobile手机号列表，以逗号,隔开;
	postParams.Add("content", url.QueryEscape(template))          //content发送内容,utf-8编码;
	//ext扩展子号;stime定时时间,格式如2009-09-01 18:21:00;rrid唯一标识,全数字;msgfmt内容编码,0：ASCII串,3：短信写卡操作,4：二进制信息,8：UCS2编码,空或15：含GB汉字.返回:唯一标识
	postParams.Add("ext", "")
	postParams.Add("stime", "")
	postParams.Add("rrid", "")
	postParams.Add("msgfmt", "")

	data := postParams.Encode()

	// Create New http Transport
	transCfg := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // disable verify
	}
	// Create Http Client
	client := &http.Client{Transport: transCfg}

	resp, err := client.Post(s.Domain, "application/x-www-form-urlencoded",
		strings.NewReader(data))

	if err != nil {
		return err
	}

	logging.Info("发送短信： %s - %s", mobile, template)

	defer resp.Body.Close()
	bs, err := ioutil.ReadAll(resp.Body)

	logging.Info(string(bs))

	if err != nil {
		return err
	}

	return nil
}
